package com.zdy.im.core;

import org.tio.core.ChannelContext;
import org.tio.websocket.common.Opcode;
import org.tio.websocket.common.WsResponse;


/**
 * @Author 作者 : zdy
 * @CreateDate 创建时间: 2021-02-30
 * @Version 版本: v1.0.0
 * <pre>
 *
 *  @Description (说明):  im发送包功能接口
 *
 * </pre>
 **/
public class ImPacket extends WsResponse implements ImConst
{
	private static final long serialVersionUID = 2000118564569232098L;
	/**
	 * 包状态码;
	 */
	protected Status status;

	/**
	 * 消息命令;
	 */
	private int command;

	protected ChannelContext imChannelContext;
	
	public ImPacket(){}
	
	public static ImPacket build(byte[] body){
		ImPacket wsResponse = new ImPacket();
		try {
			wsResponse.setWsOpcode(Opcode.TEXT);
			if(null != body){
				wsResponse.setBody(body);
			}
		} catch (Exception e) {
		}
		return wsResponse;
	}
	
	public static ImPacket build(ICommand command, byte[] body)
	{
		return build(body).setCommand(command);
	}
	
	public  static ImPacket build(ICommand command)
	{
		return build(command,null);
	}

	public static byte encodeEncrypt(byte bs,boolean isEncrypt){
		if(isEncrypt){
			return (byte) (bs | Protocol.FIRST_BYTE_MASK_ENCRYPT);
		}else{
			return (byte)(Protocol.FIRST_BYTE_MASK_ENCRYPT & 0b01111111);
		}
	}
	
	public static boolean decodeCompress(byte version)
	{
		return (Protocol.FIRST_BYTE_MASK_COMPRESS & version) != 0;
	}

	public static byte encodeCompress(byte bs, boolean isCompress)
	{
		if (isCompress)
		{
			return (byte) (bs | Protocol.FIRST_BYTE_MASK_COMPRESS);
		} else
		{
			return (byte) (bs & (Protocol.FIRST_BYTE_MASK_COMPRESS ^ 0b01111111));
		}
	}

	public static boolean decodeHasSynSeq(byte maskByte)
	{
		return (Protocol.FIRST_BYTE_MASK_HAS_SYNSEQ & maskByte) != 0;
	}

	public static byte encodeHasSynSeq(byte bs, boolean hasSynSeq)
	{
		if (hasSynSeq)
		{
			return (byte) (bs | Protocol.FIRST_BYTE_MASK_HAS_SYNSEQ);
		} else
		{
			return (byte) (bs & (Protocol.FIRST_BYTE_MASK_HAS_SYNSEQ ^ 0b01111111));
		}
	}

	public static boolean decode4ByteLength(byte version)
	{
		return (Protocol.FIRST_BYTE_MASK_4_BYTE_LENGTH & version) != 0;
	}

	public static byte encode4ByteLength(byte bs, boolean is4ByteLength)
	{
		if (is4ByteLength)
		{
			return (byte) (bs | Protocol.FIRST_BYTE_MASK_4_BYTE_LENGTH);
		} else
		{
			return (byte) (bs & (Protocol.FIRST_BYTE_MASK_4_BYTE_LENGTH ^ 0b01111111));
		}
	}

	public static byte decodeVersion(byte version)
	{
		return (byte) (Protocol.FIRST_BYTE_MASK_VERSION & version);
	}

	/**
	 * 计算消息头占用了多少字节数
	 * @return
	 * 2017年1月31日 下午5:32:26
	 */
	public int calcHeaderLength(boolean is4byteLength)
	{
		int ret = Protocol.LEAST_HEADER_LENGTH;
		if (is4byteLength)
		{
			ret += 2;
		}
		if (this.getSynSeq() > 0)
		{
			ret += 4;
		}
		return ret;
	}


	public ImPacket setCommand(ICommand type)
	{
		this.command = type.getNumber();
		return this;
	}


	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		this.status = status;
	}

	public ChannelContext getImChannelContext() {
		return imChannelContext;
	}

	public void setImChannelContext(ChannelContext imChannelContext) {
		this.imChannelContext = imChannelContext;
	}
}
